﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

namespace memo
{
    /// <summary>
    /// Az altémát megvalósító osztály.
    /// </summary>
    [Serializable]
    public class SubTopic
    {

        #region Class getter and setter.
        /// <summary>
        /// A topic címe. Nem lehet null, vagy üres.
        /// </summary>
        public string Title
        {
            get
            {
                return myTitle;
            }
            set
            {
                if (!String.IsNullOrWhiteSpace(value))
                {
                    myTitle = value;
                }
                else
                {
                    myTitle = "Untitled";
                }
            }
        }

        /// <summary>
        /// Rövid leírás, összefoglalás.
        /// </summary>
        public string ShortDescription { get; set; }

        /// <summary>
        /// A valódi tartalom, egy listában.
        /// </summary>
        public List<Content> Contents { get; set; }

        /// <summary>
        /// A tudás tesztek tárolására szolgáló lista
        /// </summary>
        public List<Test> Tests { get; set; }

        /// <summary>
        /// Visszaadja/beállítja a SubTopic ikonját. Nem lehet null.
        /// </summary>
        public string Icon
        {
            get
            {
                return myIcon;
            }
            set
            {
                if (value != null)
                {
                    myIcon = value;
                }
                else
                {
                    myIcon = "DEFAULT.png";
                }
            }
        }

        /// <summary>
        /// Visszaadja, hogy az adott SubTopicot mennyire tudja a felhasználó.
        /// </summary>
        /// <returns></returns>
        public double GetKnowledgePercent()
        {
            double percent = 0;
            if (Contents != default(List<Content>))
            {
                foreach (Content content in Contents)
                {
                    if (content != null)
                    {
                        percent += content.GetKnowledgePercent();
                    }
                }
                percent /= Contents.Count;
            }
            else
            {
                percent = 100;
            }
            return percent;
        }

        /// <summary>
        /// Nullára állítja a SubTopic tudásszázalékát.
        /// </summary>
        public void ResetKnowledgePercent()
        {
            if (Contents != default(List<Content>))
            {
                foreach (Content content in Contents)
                {
                    if (content != null)
                    {
                        content.ResetKnowledgePercent();
                    }
                }
            }
        }

        /// <summary>
        /// Százra állítja a SubTopic tudásszázalékát.
        /// </summary>
        public void FullKnowledgePercent()
        {
            if (Contents != default(List<Content>))
            {
                foreach (Content content in Contents)
                {
                    if (content != null)
                    {
                        content.FullKnowledgePercent();
                    }
                }
            }
        }
        #endregion

        #region Definition of the class' constructors.
        /// <summary>
        /// Konstruktor az osztály használatához, csak címmel.
        /// </summary>
        /// <param name="title"></param>
        public SubTopic(string title)
            : this(title, null, null, null)
        { }

        /// <summary>
        /// Konstruktor az osztály használatához, a tartalom inicializálása nélkül.
        /// </summary>
        /// <param name="title">A téma címe. Nem lehet null.</param>
        /// <param name="shortDescription">Rövid leírás a téma tartalmáról.</param>
        public SubTopic(string title, string shortDescription)
            : this(title, shortDescription, null, null)
        { }

        /// <summary>
        /// Konstruktor az osztály használatához, a tartalom inicializálása nélkül.
        /// </summary>
        /// <param name="title">...</param>
        /// <param name="shortDescription"></param>
        /// <param name="contents"></param>
        public SubTopic(string title, string shortDescription, List<Content> contents)
            : this(title, shortDescription, contents, null)
        { }



        /// <summary>
        /// Konstruktor az osztály használatához, a tartalom inicializálása egyszerre több adattal.
        /// </summary>
        /// <param name="title">A téma címe. Nem lehet null.</param>
        /// <param name="shortDescription">Rövid leírás a téma tartalmáról.</param>
        /// <param name="contents">A tartalom.</param>
        /// <param name="iconFilePath">A SubTopic ikonja.</param>
        public SubTopic(string title, string shortDescription, List<Content> contents, string icon)
        {
            if (!String.IsNullOrWhiteSpace(title))
            {
                myTitle = title;
            }
            else
            {
                myTitle = "Untitled";
            }
            ShortDescription = shortDescription;
            if (icon != null)
            {
                Icon = icon;
            }
            else
            {
                Icon = "DEFAULT.png";
            }
            Contents = contents;

            Tests = new List<Test>();
        }
        #endregion

        #region Add one item List type fields.
        /// <summary>
        /// Egy content hozzáadása.
        /// </summary>
        /// <param name="content">Hozzáadni kívánt content.</param>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool AddContent(Content content)
        {
            if (Contents != null)
            {
                Contents.Add(content);
                return true;
            }
            return false;
        }
        #endregion

        #region Remove one item List type fields.
        /// <summary>
        /// Törli a megadott indexű contentet.
        /// </summary>
        /// <param name="index">A törlendő content indexe.</param>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool RemoveContent(int index)
        {
            if (Contents != null)
            {
                if (Contents.Count > index && index >= 0)
                {
                Contents.RemoveAt(index);
                return true;
                }
            }
            return false;
        }
        #endregion

        #region Clear List type fields.
        /// <summary>
        /// Törli az összes Contentet.
        /// </summary>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool ClearContents()
        {
            if (Contents != null)
            {
                Contents.Clear();
                return true;
            }
            return false;
        }
        #endregion

        #region Swap List type elements.
        /// <summary>
        /// Felcserél két Contentet.
        /// </summary>
        /// <param name="from">Az egyik felcserélendő elem ahonna áthelyezzük.</param>
        /// <param name="to">A másik felcserélendő elem ahová az előzőt tesszük.</param>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool SwapContents(int from, int to)
        {
            if (Contents != null)
            {
                if (Contents.Count > from && from >= 0 && Contents.Count > to && to >= 0)
                {
                Content Swap = Contents[from];
                Contents[from] = Contents[to];
                Contents[to] = Swap;
                return true;
                }
            }
            return false;
        }
        #endregion

        #region Object class overwritten methods.
        /// <summary>
        /// Checks if the subtopics have the exact same title, short description, and the same contents.
        /// </summary>
        /// <param name="obj">The compared Subtopic</param>
        /// <returns>bool</returns>
        public override bool Equals(object obj)
        {
            bool equals = false;
            SubTopic subtopic = obj as SubTopic;

            if ((subtopic != null) && (GetType() == subtopic.GetType()))
            {
                if (GetHashCode() == subtopic.GetHashCode())
                {
                    if (myTitle == subtopic.myTitle && ShortDescription == subtopic.ShortDescription)
                    {
                        if (Contents == null && subtopic.Contents == null)
                        {
                            equals = true;
                        }
                        else
                        {
                            if (Contents.Count == subtopic.Contents.Count)
                            {
                                int i;
                                for (i = 0; i < Contents.Count; i++)
                                {
                                    if (Contents[i] == subtopic.Contents[i])
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                if (i == Contents.Count)
                                {
                                    equals = true;
                                }
                            }
                        }
                    }
                }
            }
            return equals;
        }

        /// <summary>
        /// Generates the hashcode for subtopic.
        /// </summary>
        /// <returns>The hashcode</returns>
        public override int GetHashCode()
        {
            int hash = myTitle.GetHashCode(); // note: title can't be null, so no checking is needed.
            if (ShortDescription != null)
            {
                hash += ShortDescription.GetHashCode();
            }
            if (Contents != null)
            {
                foreach (Content content in Contents)
                {
                    if (content != null)
                    {
                        hash += content.GetHashCode();
                    }
                }
            }

            return hash;
        }
        #endregion

        #region Class private field.
        /// <summary>
        /// A SubTopic ikonja.
        /// </summary>
        private string myIcon;

        /// <summary>
        /// A SubTopic címe.
        /// </summary>
        private string myTitle;
        #endregion
    }
}
